package com.coocaa.x.service.liteservice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;

import com.coocaa.x.framework.app.BootUpRunnable;
import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.app.CoocaaService;
import com.coocaa.x.framework.utils.Android;
import com.coocaa.x.framework.utils.FirstStart;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.framework.utils.PresetUtil;
import com.coocaa.x.service.liteservice.aidl.ILiteEntryService.Stub;
import com.coocaa.x.service.liteservice.aidl.ILiteService;
import com.coocaa.x.service.liteservice.aidl.ILiteServiceListener;
import com.skyworth.framework.skysdk.properties.SkyGeneralProperties;
import com.skyworth.framework.skysdk.properties.SkySystemProperties;

import java.util.List;

public class LiteEntryService extends CoocaaService {

    private static class MyStub extends Stub {
        private Context mContext = null;
        private boolean bBind = false;

        private BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
//                String action = intent.getAction();
//                if (action.equals(LiteServiceManager.LITE_SERVICE_ON_CREATE_BROADCAST_ACTION)) {
//                    String packageName = intent.getStringExtra("package");
//                    int version = intent.getIntExtra("version", 0);
//                    if (packageName != null) {
//                        LogUtils.d("entry", "LITE_SERVICE_ON_CREATE_BROADCAST_ACTION:" + packageName);
//                        if (!packageName.equals(mContext.getPackageName()) && version > LiteServiceConnecter.getVersion())
//                            xbind(packageName);
//                    }
//                } else if (action.equals(LiteServiceManager.LITE_SERVICE_ON_DESTROY_BROADCAST_ACTION)) {
//                    String packageName = intent.getStringExtra("package");
//                    if (packageName != null) {
//                        LogUtils.d("entry", "LITE_SERVICE_ON_DESTROY_BROADCAST_ACTION:" + packageName);
//                    }
//                }
            }
        };

        public MyStub(Context context) {
            mContext = context;
            IntentFilter filter = new IntentFilter();
            filter.addAction(LiteServiceManager.LITE_SERVICE_ON_CREATE_BROADCAST_ACTION);
            filter.addAction(LiteServiceManager.LITE_SERVICE_ON_DESTROY_BROADCAST_ACTION);
            mContext.registerReceiver(receiver, filter);
            xbind(mContext.getPackageName());
        }

        private String getCurrentService() {
            PackageManager pm = mContext.getPackageManager();
            List<ResolveInfo> list = pm.queryIntentServices(new Intent(LiteServiceConnecter.ACTION),
                    PackageManager.GET_INTENT_FILTERS);
            LogUtils.d("entry", "size:" + list.size());
            for (ResolveInfo r : list) {
                LogUtils.d("entry", "pkgname:" + r.serviceInfo.applicationInfo.packageName + "   enable:"
                        + r.serviceInfo.enabled);
                if (!r.serviceInfo.applicationInfo.packageName.equals(mContext.getPackageName())
                        && r.serviceInfo.enabled)
                    return r.serviceInfo.applicationInfo.packageName;
            }
            return mContext.getPackageName();
        }

        private void enableMyService() {
            LogUtils.d("entry", "########################enableMyService:" + mContext.getPackageName());
            LiteServiceConnecter.setEnable(mContext, true);
        }

        private void bindMyService() {
            bindLiteServiceAndStartIt(mContext.getPackageName());
        }

        private void bindLiteServiceAndStartIt(final String pkgName) {
            CoocaaApplication.post(new Runnable() {
                @Override
                public void run() {
                    LogUtils.d("entry", "########################bindLiteService:" + pkgName);
                    LiteServiceConnecter.connecter.bindService(mContext, pkgName);

                    try {
                        LogUtils.d("entry", "########################startLiteService:" + LiteServiceConnecter.connecter.getPackageName());
                        getLiteService().addListener(stub);
                        getLiteService().start();
                        getLiteService().whoAmI();
                        startChecker();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        private void unbindCurrentService() throws RemoteException {
            LogUtils.d("entry", "########################unbindCurrentService:" + LiteServiceConnecter.connecter.getPackageName());
            LiteServiceConnecter.connecter.unbindService(mContext);
        }

        private void stopCurrentService() {
            try {
                LogUtils.d("entry", "########################stopLiteService:" + LiteServiceConnecter.connecter.getPackageName());
                getLiteService().stop();
                getLiteService().removeListener(stub);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        private void xbind(final String target) {
            CoocaaApplication.post(new Runnable() {
                @Override
                public void run() {
                    synchronized (MyStub.this) {
                        if (bBind)
                            return;
                        bBind = true;
                        CoocaaApplication.wait4SystemBootcompleteFlag();
//                        String currentService = mContext.getPackageName();
//                        if (target == null)
//                            currentService = getCurrentService();
//                        LogUtils.d("entry", "#######################currentService:" + currentService);
//
//                        if (!currentService.equals(mContext.getPackageName())) {
//                            try {
//                                bindLiteService(currentService);
//                                int version = getLiteService().getVersion();
//                                int my_version = LiteServiceConnecter.getVersion();
//
//                                LogUtils.d("entry", "###########################my_version:" + my_version + "   version:" + version);
//                                if (my_version > version) {
//                                    stopCurrentService();
//                                    unbindCurrentService();
//
//                                    enableMyService();
//                                    bindMyService();
//                                }
//                                startLiteService();
//                            } catch (RemoteException e) {
//                                e.printStackTrace();
//                            }
//                        } else {
                        enableMyService();
                        bindMyService();
//                        }
//                        startChecker();
                    }
                }
            });
        }

        private boolean bCheckerStarted = false;

        private void startChecker() {
            synchronized (this) {
                if (bCheckerStarted)
                    return;
                bCheckerStarted = true;
                Runnable check = new Runnable() {
                    @Override
                    public void run() {
                        if (!LiteServiceConnecter.connecter.isAlive()) {
                            synchronized (MyStub.this) {
                                LiteServiceConnecter.connecter.unbindService(mContext);
                                bBind = false;
                                xbind(null);
                            }
                        }
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        CoocaaApplication.post(this);
                    }
                };
                CoocaaApplication.post(check);
            }
        }

        @Override
        public ILiteService getLiteService() throws RemoteException {
            return LiteServiceConnecter.connecter.getService();
        }

        private ILiteServiceListener.Stub stub = new ILiteServiceListener.Stub() {
            @Override
            public void willOnStop() throws RemoteException {
                synchronized (MyStub.this) {
                    LogUtils.d("entry", "^^^^^^^willOnStop");
                    getLiteService().removeListener(stub);
                    LiteServiceConnecter.connecter.unbindService(mContext);
                    bBind = false;
                }
            }
        };
    }

    /**
     * 每个应用可以在androidmanifest中配置此为key的meta-data,value为Runnable的实现，开机后会有liteservice调用，多个实现用|隔开
     */
    private static final String BOOTUP_RUNNABLE = "bootup_runnable";

    private void handleBootUp(Context context, String action) {
        String runnables = (String) Android.getMetaData(context,
                context.getPackageName(), BOOTUP_RUNNABLE);
        if (runnables != null) {
            String[] _runnables = runnables.split("\\|");

            for (String r : _runnables) {
                try {
                    BootUpRunnable run = (BootUpRunnable) Class.forName(r).newInstance();
                    run.setAction(action);
                    run.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static final int BOOTUP_TIME = 80;


    private boolean bHandleBootUp = false;

    private static final String BOOTUP_FLAG = "third.get.appstore.bootupflag";


    private static final String COOCAATV_READY_FLAG = "third.get.appstore.canbootup";

    private void wait4CoocaaTvReady() {
        long tvVersion = Android.getVersionCode(CoocaaApplication.getContext(), "com.tianci.tv");
        LogUtils.d("current coocaaTv version:" + tvVersion);
        if (CoocaaApplication.isCoocaaSystem() && tvVersion >= 2) {
            while (true) {
                String v = SkySystemProperties.getProperty(COOCAATV_READY_FLAG);
                LogUtils.d("sds", "COOCAATV_READY_FLAG:" + v);
                if ((v == null || !v.equals("true"))) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    break;
                }
            }
        }
    }

    private boolean bStarted = false;

    @Override
    public synchronized int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null)
            return super.onStartCommand(intent, flags, startId);
        final String action = intent.getStringExtra("action");
        if (!bStarted || (action != null && action.equals(BootUpRunnable.QUICK_RESUME_ACTION))) {
            bStarted = true;
            postOnSingleThread(new Runnable() {
                @Override
                public void run() {
                    CoocaaApplication.wait4SystemBootcompleteFlag();
                    String value = SystemProperties.get(BOOTUP_FLAG);
                    if (value == null || value.equals("") || !value.equals("true")) {
                        bHandleBootUp = false;
                        SystemProperties.set(BOOTUP_FLAG, "true");
                    } else
                        bHandleBootUp = true;
                    LogUtils.d("handleBootUp:" + bHandleBootUp + "   action:" + action + "  BOOTUP_FLAG:" + value);


                    boolean flag = false;
                    if (action != null && action.equals(BootUpRunnable.QUICK_RESUME_ACTION))
                        flag = true;
                    if (bHandleBootUp && !flag)
                        return;

                    if (!SkyGeneralProperties.getBoolProperty("NEW_BOOT_FLOW"))
                        wait4CoocaaTvReady();
                    handleBootUp(getContext(), action);
                }
            });
        }
        return super.onStartCommand(intent, flags, startId);
    }


    private MyStub stub = null;

    @Override
    public void onCreate() {
        super.onCreate();
        stub = new MyStub(this);
        boolean isFirstStart = FirstStart.isFirstStart(this, "appstore_service", FirstStart.ACTION.FIRST_VERSION);
        LogUtils.d("preset", "start service....isFirstStart:" + isFirstStart);
        if (isFirstStart) {
            FirstStart.markFirstStartFlag(this, "appstore_service");
            CoocaaApplication.post(new Runnable() {
                @Override
                public void run() {
                    PresetUtil.PresetApp();
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return stub;
    }
}
